import logging

from decorator import decorator
from google.appengine.api import users

from biahanoi.lib.base import *
from biahanoi.forms import DiaryFormSchema
from biahanoi.model import Diary

log = logging.getLogger(__name__)

@decorator
def admin(func, *args, **kargs):
    if users.is_current_user_admin():
        return func(*args, **kargs)
    abort(404)


class DiariesController(BaseController):
    """REST Controller styled on the Atom Publishing Protocol"""
    # To properly map this controller, ensure your config/routing.py file has
    # a resource setup:
    #     map.resource('diary', 'diaries')

    items_per_page = 10

    def _get_entry_or_404(self, id):
        try:
            entry = Diary.get_by_id(int(id))
            if not entry:
                abort(404)
        except ValueError:
            abort(404)
        return entry

    def index(self, format='html'):
        """GET /diaries: All items in the collection."""
        # url_for('diaries')
        c.entries = Diary.all().filter('is_active = ', True)\
                         .order("-pub_date")[:self.items_per_page]
        return render('diary/index.mak')

    @admin
    @validate(schema=DiaryFormSchema(), form='new')
    def create(self):
        """POST /diaries: Create a new item."""
        # url_for('diaries')
        diary = Diary(title=self.form_result['title'],
                      content=self.form_result['content'],
                      pub_date=self.form_result['pub_date'],
                      creator=users.get_current_user(),
                      modifier=users.get_current_user(),
                      )
        diary.put()
        redirect_to(controller='diaries', action='index')

    @admin
    def new(self, format='html'):
        """GET /diaries/new: Form to create a new item."""
        # url_for('new_diary')
        return render('diary/form.mak')

    @admin
    @validate(schema=DiaryFormSchema(), form='edit')
    def update(self, id):
        """PUT /diaries/id: Update an existing item."""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="PUT" />
        # Or using helpers:
        #    h.form(h.url_for('diary', id=ID),
        #           method='put')
        # url_for('diary', id=ID)
        entry = self._get_entry_or_404(id)
        entry.title = self.form_result['title']
        entry.content = self.form_result['content']
        entry.pub_date = self.form_result['pub_date']
        entry.modifier = users.get_current_user()
        entry.put()
        redirect_to(controller='diaries', action='index')

    @admin
    def delete(self, id):
        """DELETE /diaries/id: Delete an existing item."""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="DELETE" />
        # Or using helpers:
        #    h.form(h.url_for('diary', id=ID),
        #           method='delete')
        # url_for('diary', id=ID)
        pass

    def show(self, id, format='html'):
        """GET /diaries/id: Show a specific item."""
        # url_for('diary', id=ID)
        c.entry = self._get_entry_or_404(id)
        return render('diary/show.mak')

    @admin
    def edit(self, id, format='html'):
        """GET /diaries/id;edit: Form to edit an existing item."""
        # url_for('edit_diary', id=ID)
        c.entry = self._get_entry_or_404(id)
        return render('diary/edit.mak')
